package com.suxii.handler;

import com.google.gson.Gson;
import com.suxii.pojo.ChatMsg;
import com.suxii.pojo.ChatUser;
import com.suxii.pojo.LoginMsg;
import com.suxii.service.UserService;
import io.netty.channel.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

@Slf4j
@ChannelHandler.Sharable
@Component("CHAT_HANDLER")
public class ChatHandler extends SimpleChannelInboundHandler<ChatMsg> {

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void channelRead0(ChannelHandlerContext ctx, ChatMsg msg) throws Exception {
        //log.info("ChatHandler:{}",msg);
        //ChatMsg chatMsg=(ChatMsg)msg;
        // 获取目标uid
        int aimUid = msg.getUuid();
        // 通过uid获取目标channel
        Channel aimCh = ChannelsHandler.channelMap.get(aimUid);
        // 过滤匹配目标产channel
        Stream<Channel> stream = ChannelsHandler.channelGroup.stream().filter(o -> o.equals(aimCh));
        if (stream.findAny().isPresent()) { // 判断流中是不是当前目标  Present -》 目前
            ChannelsHandler.channelGroup.stream().filter(o -> o.equals(aimCh)).forEach(p -> p.writeAndFlush(msg));
        } else {
            if (isHave(aimUid)) {
                // 以自己的uid作为key，hset 目标uid，消息内容
                try {
                    List<String> message = ChannelsHandler.messageCache.get(aimUid);
                    String json;
                    if (message == null) {
                        List<String> l = new ArrayList<>();
                        l.add(msg.getContent());
                        ChannelsHandler.messageCache.put(aimUid, l);
                        json = new Gson().toJson(l);
                    } else {
                        message.add(msg.getContent());
                        // json序列化算法
                        json = new Gson().toJson(message);
                    }
                    redisTemplate.opsForHash().put(String.valueOf(aimUid), String.valueOf(msg.getUid()), json);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //redisTemplate.opsForHash().put("123","222","hahahhahah");
                log.info("当前用户不在线");
            } else {
                log.info("当前用户不存在");
            }
        }
        //super.channelRead(ctx, msg);
    }

    @Autowired
    private UserService userService;

    private boolean isHave(int uuid) {
        // TODO 减少数据库访问，
        //  查询先判断Map集合中是否存在该uid，第一次查询若不在线，将uid封装到Map集合中，
        //  当目标uid上线时，先遍历List集合
        //  如果存在，就删除掉当前uid

        Integer noConnectUser = ChannelsHandler.noConnectUserCache.get(uuid);
        if (noConnectUser != null) {
            return true;
        }

        Long count = userService.lambdaQuery()
                .select(ChatUser::getUid)
                .eq(ChatUser::getUid, uuid)
                .count();

        // 查询到才添加到List集合
        if (count > 0) {
            ChannelsHandler.noConnectUserCache.put(uuid, uuid);
        }
        return count > 0;
    }
}
